/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package braipetro.client.regras;

/**
 *
 * @author aqbs
 */
import java.util.Stack;

public class InfixToPostfixConverterTESTE {

    Stack<String> pilha = new Stack<String>();
    int pointer = 1;

    public String converterToPostFix(String infix) {
        int abriuParenteses = 0;
        String negacao = "";
        infix += ")";
        String[] ex = infix.split("");
        pilha.push("(");
        String postfix = "";
        while (!pilha.empty()) {
            if ((isADigit(ex[pointer])) && (!ex[pointer].equals(")"))
                    && (!ex[pointer].equals("("))) { //verifica se é digito e se é um paratenses ( ou )
                postfix += ex[pointer]; //adiciona o digito se for verdadeiro acima
                if (abriuParenteses == 0 && !(negacao.isEmpty())) { 
                        postfix += negacao;
                        negacao = "";
                    }
            }
            if (ex[pointer].equals("(")) //Se não é um digito ele é um (? Se for adicione na pilha
            {
                pilha.push(ex[pointer]);
                abriuParenteses++;
            }
            if (ex[pointer].equals("!")) {
                negacao = ex[pointer];
            }
            if (isOperator(ex[pointer])) {
                if (isOperator(pilha.peek())) {// No topo da pilha existe um operador? 
                    while (precedence(pilha.peek(), ex[pointer])) {
                        postfix += pilha.pop();
                    }
                }
                pilha.push(ex[pointer]);
            }
            if (ex[pointer].equals(")")) {
                abriuParenteses--;
                postfix = removeFromStackUntilFindRightParenthesis(postfix);
                if (!negacao.isEmpty() && abriuParenteses == 0) {
                    postfix += negacao;
                    negacao = "";
                }
            }
            pointer++;
        }
        return postfix;
    }

    private String removeFromStackUntilFindRightParenthesis(String postfix) {
        while (!pilha.peek().equals("(")) {
            postfix += pilha.pop();
        }
        pilha.pop();
        return postfix;
    }

    public static boolean isADigit(String digit) {
        String[] symbols = {"+", "-", "*", "/", "^", "!"};
        boolean isSymbol = true;
        for (String symbol : symbols) {
            if (digit.equals(symbol)) {
                isSymbol = false;
            }
        }
        return isSymbol;
    }

    private boolean isOperator(String ch) {
        if ((ch.equals("+")) || (ch.equals("-")) || (ch.equals("*"))
                || (ch.equals("/")) || (ch.equals("^"))) {
            return true;
        } else {
            return false;
        }
    }

    public static boolean precedence(String top, String ex) {
        if (top.equals(ex)) //o elemento topo é igual ao novo que sera inserido na pila?
        {
            return true;
        } else if (((top.equals("*")) || (top.equals("/"))) && (ex.equals("+")) //senao veja se ele é um * ou /, caso ele nao seja sera + ou - e retorne falso 
                || (ex.equals("-"))) {
            return true;
        } else {
            return false;
        }
    }

    public static void main(String[] args) {
        InfixToPostfixConverterTESTE f = new InfixToPostfixConverterTESTE();
        System.out.println(f.converterToPostFix("A+!(A+B)"));
        // System.out.println("+".equals(")"));
    }

}
